package com.plateform.shardingsphere.config;





import com.plateform.shardingsphere.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;
/**
 * @ClassName ShardingAlgorithmTool
 * @Description: TODO
 * @Author liupantao
 * @Date 2022/10/20
 * @Version V1.0
 **/
@Slf4j
@Component
@Order(12)
public class ShardingAlgorithmTool {
    private static final HashSet<String> tableNameCache = new HashSet<>();
    /**
     * 判断 分表获取的表名是否存在 不存在则自动建表
     *
     * @param logicTableName  逻辑表名(表头)
     * @param resultTableName 真实表名
     * @return 确认存在于数据库中的真实表名
     */
    public static String shardingTablesCheckAndCreatAndReturn(String logicTableName, String resultTableName) {
        synchronized (logicTableName.intern()) {
            // 缓存中有此表 返回
            if (tableNameCache.contains(resultTableName)) {
                return resultTableName;
            }
            // 缓存中无此表 建表 并添加缓存
            List<String> sqlList = selectTableCreateSql(logicTableName);
            for (int i = 0; i < sqlList.size(); i++) {
                sqlList.set(i, sqlList.get(i).replace("CREATE TABLE", "CREATE TABLE IF NOT EXISTS").replace(logicTableName.toLowerCase(), resultTableName.toLowerCase()));
            }
            boolean b = executeSql(sqlList);
            if(b){
                tableNameCache.add(resultTableName);
            }
        }
        return resultTableName;
    }

    /**
     * 缓存重载方法
     */
    public static void tableNameCacheReload() {
        // 读取数据库中所有表名
        List<String> tableNameList = getAllTableNameBySchema();
        // 删除旧的缓存(如果存在)
        tableNameCache.clear();
        //为适配以前项目，简单处理

        // 写入新的缓存
        tableNameCache.addAll(tableNameList);
    }




    private static boolean executeSql(List<String> sqlList) {
        Environment env = SpringUtils.getApplicationContext().getEnvironment();
        boolean isFlag=false;
        try (Connection conn = DriverManager.getConnection(Objects.requireNonNull(env.getProperty("spring.shardingsphere.datasource.master.url")), env.getProperty("spring.shardingsphere.datasource.master.username"), env.getProperty("spring.shardingsphere.datasource.master.password"))) {
            try (Statement st = conn.createStatement()) {
                conn.setAutoCommit(false);
                for (String sql : sqlList) {
                    st.execute(sql);
                }
                conn.commit();
                isFlag=true;
            } catch (Exception ex) {
                conn.rollback();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return  isFlag;
    }

    private static List<String> selectTableCreateSql(String tableName) {
        List<String> res = new ArrayList<>();
        if (tableName.equalsIgnoreCase("t_pressure_data")) {
            res.add("CREATE TABLE `t_pressure_data`  (\n" +
                    "   `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,\n" +
                    "  `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'name',\n" +
                    "  `create_time` datetime NULL DEFAULT NULL COMMENT '数据时间',\n" +
                    "  PRIMARY KEY (`id`) USING BTREE\n" +
                    ") ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '数据表' ROW_FORMAT = Dynamic;\n"

            );
        }
        return res;
    }

    public static List<String> getAllTableNameBySchema() {
        List<String> res = new ArrayList<>();
        ApplicationContext applicationContext = SpringUtils.getApplicationContext();
        Environment env = applicationContext.getEnvironment();
        try (Connection connection = DriverManager.getConnection(env.getProperty("spring.shardingsphere.datasource.master.url"), env.getProperty("spring.shardingsphere.datasource.master.username"), env.getProperty("spring.shardingsphere.datasource.master.password"));
             Statement st = connection.createStatement()) {
            //String sql="select name from sysobjects where name like 't_pressure_data%'";
             String sql="show tables like 't_pressure_data%'";  //mysql
            try (ResultSet rs = st.executeQuery(sql)) {
                while (rs.next()) {
                    res.add(rs.getString(1).toLowerCase());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    public static HashSet<String> cacheTableNames() {
        return tableNameCache;
    }
}

